package com.ken.astroboy.logic;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.ken.astroboy.core.Constant;
import com.ken.astroboy.core.InMemoryStorage;
import com.ken.astroboy.model.*;
import com.ken.astroboy.quartz.QuartzManager;
import com.ken.astroboy.robot.*;
import com.ken.astroboy.service.*;
import com.ken.astroboy.util.*;
import com.ken.astroboy.vo.AdminVo;
import com.ken.astroboy.vo.AutoReplyVo;
import com.ken.astroboy.vo.FriendVo;
import com.ken.astroboy.vo.GroupVo;
import com.ken.astroboy.vo.MemberVo;
import com.ken.astroboy.vo.ScheduledTaskVo;
import com.ken.astroboy.vo.WelcomeMsgVo;

public class LogicProcess {

	private static final Logger logger = LoggerFactory.getLogger(LogicProcess.class);
	private static Robot robot = new MoLiRobot();	

	//group是微信群的Nick Name， member使用打卡用户的Nick Name
	public static void processSignIn(String groupUserName, String group, String member, long attrStatus) throws IOException{

		if(!isGroupHasSignInFunction(group)){
			logger.info("微信群 [{}] 没有开启打卡功能，不处理。", group);
			return;
		}
			
		Calendar calendar = Calendar.getInstance();	
		//一天的毫秒数=24*60*60*1000
		//long dayInMillis = 86400000;
		long currentTimeMillis = System.currentTimeMillis();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式		
		String currentTime = sdf.format(currentTimeMillis);

		//当前时间在一年中的天数
		calendar.setTimeInMillis(currentTimeMillis);	
		int day = calendar.get(Calendar.DAY_OF_MONTH);

		//取当前时间再往前推一天
		//因为Calendar.WEEK_OF_YEAR是把星期天作为一周的开始		
		//如果要以星期一作为一周的开始，那么计算当前日期所在周数的时候，往前推一天
		//calendar.setTimeInMillis(currentTimeMillis - dayInMillis);			
		//int week = calendar.get(Calendar.WEEK_OF_YEAR);

		//文件名为微信群名字+当前时间周数
		String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";
		
		//String fileContent = getSignInFileContent(fileName);
		String fileContent = FileUtil.read(fileName, Constant.encoding);

		SignInRecord record = null;
		int signInTimes = 0;
		int totalTimes = 0;
		boolean repeatSignIn = false;

		if(fileContent == null){
			logger.info("打卡记录文件还不存在，生成一个新的Record对象");

			//第一次打卡，打卡次数为1
			signInTimes = 1;
			totalTimes = 1;
			//新的记录详情，member这个用户在day这一天打了1次卡
			SignInDetail detail = new SignInDetail(member, signInTimes, totalTimes, day, attrStatus);		
			//添加到详情列表
			List<SignInDetail> detailList = new ArrayList<SignInDetail>();			
			detailList.add(detail);			
			//新的记录项，记录group这个微信群的所有打卡活动
			SignInRecordItem recordItem = new SignInRecordItem(group, detailList);		
			//添加到记录项列表
			List<SignInRecordItem> recordList = new ArrayList<SignInRecordItem>();			
			recordList.add(recordItem);		
			//设置记录项列表到总记录对象
			record = new SignInRecord(recordList);

		}else{

			logger.info("打卡记录文件已存在，从文件内容中解析出Record对象");

			record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

			if(record != null){
				boolean memberFound = false;
				boolean groupFound = false;

				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(group)){

							groupFound = true;

							for(SignInDetail detail: recordItem.getDetail()){
								
								if(member.equals(detail.getMember())){
									logger.info("找到该用户的记录，开始修改其打卡记录");
									signInTimes = detail.getTimes();
									totalTimes = detail.getTotal();
									if(detail.getDay() != day){
										//给该用户增加一次打卡记录
										signInTimes++;
										totalTimes++;
										detail.setTimes(signInTimes);
										detail.setTotal(totalTimes);
										//更新打卡日期
										detail.setDay(day);
									}else{
										logger.info("该用户是重复打卡");
										//同一天重复打卡
										repeatSignIn = true;
									}
									memberFound = true;
									break;
								}
							}

							if(!memberFound){
								logger.info("找到该用户所在群的记录，但没有该用户的记录，开始添加新的打卡记录");
								//该用户第一次打卡，新建一个打卡详情记录并添加
								signInTimes = 1;
								totalTimes = 1;
								SignInDetail detailNew = new SignInDetail(member, signInTimes, totalTimes, day, attrStatus);
								recordItem.getDetail().add(detailNew);
							}
						}

						if(memberFound){
							break;
						}
					}

					if(!groupFound){
						//这种情况正常是不会出现的，其实可以不用处理这种情况

						logger.info("没有该用户所在群信息（这种情况一般不会出现），开始添加群信息和其打卡记录");
						//第一次打卡，打卡次数为1
						signInTimes = 1;
						totalTimes = 1;
						//新的记录详情，member这个用户在day这一天打了1次卡
						SignInDetail detail = new SignInDetail(member, signInTimes, totalTimes, day, attrStatus);		
						//添加到详情列表
						List<SignInDetail> detailList = new ArrayList<SignInDetail>();			
						detailList.add(detail);			
						//新的记录项，记录group这个微信群的所有打卡活动
						SignInRecordItem recordItem = new SignInRecordItem(group, detailList);		
						//添加到记录项列表
						List<SignInRecordItem> recordList = new ArrayList<SignInRecordItem>();			
						recordList.add(recordItem);		
						//设置记录项列表到总记录对象
						record.setRecord(recordList);									
					}

				}else{
					logger.info("出错-打卡文件JSON解析出来Record对象内的record列表为空");
				}								
			}else{
				logger.info("出错-打卡文件JSON解析出来Record对象为空");
			}			
		}

		if(record != null){	
			if(!repeatSignIn){
				if(signInTimes > 0){

					logger.info("用户 " + member + "在微信群 " + group + " 打卡成功。 " + "打卡时间：" + currentTime + " 总打卡次数为： " + signInTimes + " 开始记录到文件...");

					String recordStr = JSON.toJSONString(record);
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
					logger.info("用户 [" + member + "]在微信群[" + group + "]打卡成功,记录已经成功写入文件 " + fileName);						
					logger.info("给群里发消息通知用户打卡情况");		
					sendNotifyMsg(groupUserName, group, member, signInTimes, totalTimes, repeatSignIn);	

				}else{
					logger.info("出错-打卡次数出现异常，次数为： " + signInTimes);
				}						
			}else{
				logger.info("用户 [" + member + "]在微信群[" + group + "]重复打卡 ");
				logger.info("给群里发消息通知用户重复打卡");		
				sendNotifyMsg(groupUserName, group, member, signInTimes, totalTimes, repeatSignIn);	
			}						
		}else{
			logger.info("出错-生成的打卡记录Record对象为空，打卡处理失败 ");
		}

	}

	
	private static void processQuestionCollection(String question,
													String groupUserName, String groupNickName, String senderNickName) throws IOException{

		StringBuilder sb = new StringBuilder();
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
		sb.append(String.format("%-28s\n", sdf.format(System.currentTimeMillis())))
		  .append(String.format("%-18s\n", groupNickName))
		  .append(String.format("%-12s\n", senderNickName))
		  .append(question).append("\r\n");
							
		WxService.sendTextMsg("问题已经搜集到问题库，请关注微信公众号 ：“有浪花的小恒星”, 我们会将大家的问题搜集归类，按专题进行统一回复。", groupUserName);
					
		//写入文件			
		FileUtil.write(Constant.questionFile, sb.toString(), Constant.encoding, true);
		
	}
	
		
	private static void sendNotifyMsg(String groupUserName, String group, String member, 
			int signInTimes, int totalTimes, boolean repeatSignIn){

		StringBuilder sb = new StringBuilder();

		sb.append("@").append(member);
		if(repeatSignIn){
			sb.append(" 您今天打过卡啦[调皮]\r");
		}else{
			sb.append(" 打卡成功[微笑]\r");
		}
		sb.append("本周打卡次数： ").append(signInTimes).append("次\r");
		sb.append("累计打卡次数： ").append(totalTimes).append("次");

		WxService.sendTextMsg(sb.toString(), groupUserName);
	}
	
	
	public static void sendWelcomeMsg(String groupNickName, List<String> memberNickNameList){
				
		WelcomeMsgItem welcomeMsgItem = findWelcomeMsgItem(groupNickName);

		if(welcomeMsgItem != null){
			
			if(welcomeMsgItem.getMsgStatus() == WelcomeMsgItem.ENABLED){
				StringBuilder sb = new StringBuilder();
	
				if(memberNickNameList != null){
					for(String member : memberNickNameList){
						sb.append("@").append(member).append(", ");
					}			
				}
				
                String groupUserName = InMemoryStorage.findGroupUserName(groupNickName);

				if(welcomeMsgItem.getTextList() != null){
				    if(welcomeMsgItem.getTextList().size() > 0){
		                sb.append(welcomeMsgItem.getTextList().get(0)); 
		                WxService.sendTextMsg(sb.toString(), groupUserName);
		                
		                if(welcomeMsgItem.getTextList().size() > 1){
		                    WxService.sendTextMsg(welcomeMsgItem.getTextList().get(1), groupUserName);
		                }
				    }
				}
				
				if(welcomeMsgItem.getImageList() != null){
				    if(welcomeMsgItem.getImageList().size() > 0){
		                WxService.sendImgMsg(welcomeMsgItem.getImageList().get(0), groupUserName);
				    }
				}
			}else{
				logger.info("[{}]的欢迎消息已被停用", groupNickName);
			}			
		
		}else{
			logger.info("[{}]没有配置欢迎消息", groupNickName);
		}
	}
	
	public static String getSignInRecord(String group) throws IOException{
		
		//Calendar calendar = Calendar.getInstance();	
		//一天的毫秒数=24*60*60*1000
		//long dayInMillis = 86400000;
		//long currentTimeMillis = System.currentTimeMillis();
		
		//取当前时间再往前推一天
		//因为Calendar.WEEK_OF_YEAR是把星期天作为一周的开始		
		//如果要以星期一作为一周的开始，那么计算当前日期所在周数的时候，往前推一天
		//calendar.setTimeInMillis(currentTimeMillis - dayInMillis);			
		//int week = calendar.get(Calendar.WEEK_OF_YEAR);
			
		//文件名为微信群名字+当前时间周数
		//String fileName = "打卡记录-" + group + "-Week" + Integer.toString(week) + ".txt";
		String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";
		
		String fileContent = FileUtil.read(fileName, Constant.encoding);
		
		StringBuilder signInRecord = new StringBuilder();
				
		if(StringUtils.isNotEmpty(fileContent)){

			SignInRecord record = null;

			record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 
	
			if(record != null){					
				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(group)){

							//先按照总打卡次数从多到少排列
							Collections.sort(recordItem.getDetail(), new Comparator<SignInDetail>(){

								@Override
								public int compare(SignInDetail o1, SignInDetail o2) {

									if(o1.getTotal() < o2.getTotal()){
										return (int) 1;
									}else if (o1.getTotal() == o2.getTotal()){
										return 0;
									}else{
										return -1;
									}
								}
							});
							
							//再按照周打卡次数从多到少排列
							Collections.sort(recordItem.getDetail(), new Comparator<SignInDetail>(){

								@Override
								public int compare(SignInDetail o1, SignInDetail o2) {

									if(o1.getTimes() < o2.getTimes()){
										return (int) 1;
									}else if (o1.getTimes() == o2.getTimes()){
										return 0;
									}else{
										return -1;
									}
								}
							});						

							int numToDisplay = 0;
							int numSignInMember = recordItem.getDetail().size();

							String tmp = "(共计" + numSignInMember + "人打卡):\r\n";
							int limit = Integer.parseInt(Constant.limitInSigninRecordDisplay);
							if(numSignInMember > limit){
								tmp = "(共计" + numSignInMember + "人打卡，按周记录取前" + limit + "名展示):\r\n";
							}

							signInRecord.append("打卡记录")
							.append(tmp)
							.append(String.format("%-4s","本周"))
							.append(String.format("%-6s","总次数"))
							.append(String.format("%-10s\n","昵称"));

							for(SignInDetail detail: recordItem.getDetail()){
								//仅打印排名前三十
								if(++numToDisplay == 30){ 
									break;
								}

								signInRecord.append(String.format("%4d      ",detail.getTimes()))
								            .append(String.format("%4d      ",detail.getTotal()))
								            .append(String.format("%-10s\n", detail.getMember()));
							}

							break;
						}
					}

				}
			}
		}
		
		return signInRecord.toString();
	}
	
	
	public static void handleSyncResponse(WebWxSyncResponse response) throws IOException{

		logger.info("处理Sync Response开始...");
		
		long count = response.getAddMsgCount();
		
		logger.info("addMsgList内消息数量：" + count);
		
		if(count > 0){
			for (AddMsgListItem msgListItem : response.getAddMsgList()) {
						
				long msgType = msgListItem.getMsgType();
				//对于点对点消息，content就是有效消息;
				//对于群里面的消息，content被:"<br/>"分隔为两部分，前一部分是SenderUserName，后一部分 有效消息
				String content = msgListItem.getContent();
				//对于点对点消息，fromUserName就是SenderUserName，对于群里面的消息，fromUserName是groupUserName
				String fromUserName = msgListItem.getFromUserName();
				//String groupNickName = WechatContact.findGroupNickName(fromUserName);
				String toUserName = msgListItem.getToUserName();			
				
				if (msgType == 51) {
					//微信系统消息			
					logger.info("=========================");
					logger.info("收到微信Type 51消息");
				} else if (msgType == 1) {
					//文本消息
					logger.info("=========================");
					logger.info("收到文本消息");
					
					if (Constant.FILTER_USERS.contains(toUserName)) {
						//特殊账号发来的消息
						logger.info("--此特殊账号发来的消息");
						continue;
					} else if (fromUserName.equals(WxService.user.getUserName())) {
						//自己发来的消息
						logger.info("--此消息是自己发出来的");
						continue;
					} else if (toUserName.indexOf("@@") != -1) {
						logger.info("--不知道是什么情况");
						continue;
					} else if (fromUserName.startsWith("@@")){	
						
						logger.info("--来自群的消息");					
						//msg.getString("FromUserName")代表哪个群, content中:<br/>前面的部分代表哪个人
						processTextMsgFromGroup(fromUserName, content);
						
					} else{
						//个人点对点发过来的消息
						processTextMsgFromFriend(fromUserName, content);
					}
				} else if (msgType == 3) {
					//图片消息
					logger.info("=========================");
					logger.info("收到图片");
					
					if (fromUserName.startsWith("@@")){					
						//来自群的图片消息
						String msgId = msgListItem.getMsgId();
						processImgMsgFromGroup(msgId, fromUserName, content);										
					}
	
				} else if (msgType == 34) {
					//语音消息
					logger.info("=========================");
					logger.info("收到语音");
				} else if (msgType == 42) {
					//名片消息
					logger.info("=========================");
					logger.info("收到名片:");
				} else if (msgType == 10000) {
					//Msg Type = 10000
					logger.info("=========================");
					logger.info("收到Msg Type = 10000消息");
					logger.info("content：{}", content);
					
					processMsgType10000(response);
				}
			}			
		}else{
			//添加好友成功时，syncCheck返回seletor = 6，webWxSync返回值没有AddMsgList，但是有ModContactList，新的好友在ModContactList中
			processNewFriendAddedMsg(response);
		}

		
		logger.info("处理Sync Response结束");
	}

	
	public static void handleInitResponse(WebWxInitResponse response){	

		logger.info("处理微信初始化Response开始...");
		//Init阶段得到的Group的Member list，只有User Name, Nick Name为空，需要在batch contact阶段获取微信群成员详情
		if(response.getBaseResponse() != null){
			if(response.getBaseResponse().getRet() == 0){
								
				//把自己加入好友列表
				InMemoryStorage.friendMap.put(response.getUser().getNickName(), response.getUser().clone());
				
				for(Contact contact : response.getContactList()){
					if(contact.getUserName().startsWith("@@")){
						if(StringUtils.isNotBlank(contact.getNickName())){
							Contact contactNew = new Contact();
							contactNew.setNickName(contact.getNickName());
							contactNew.setUserName(contact.getUserName());
							contactNew.setChatRoomId(contact.getChatRoomId());
							contactNew.setEncryChatRoomId(contact.getEncryChatRoomId());
							contactNew.setVerifyFlag(contact.getVerifyFlag());
	
							String nickName = contact.getNickName();
	
							InMemoryStorage.groupMap.put(nickName, contactNew);
							
							if(nickName.contains("减肥")){
								if(!InMemoryStorage.gymGroupList.contains(nickName)){
									InMemoryStorage.gymGroupList.add(nickName);
								}
							}
							
							logger.info("-------------------------------------------");
							logger.info("微信群信息");
							logger.info("NickName : " + InMemoryStorage.groupMap.get(contact.getNickName()).getNickName());
							logger.info("UserName : " + InMemoryStorage.groupMap.get(contact.getNickName()).getUserName());
							logger.info(" ");							
						}						
					}
				}
			}					
		}

		logger.info("处理微信初始化Response结束");
	}

	
	public static void handleGetContactResponse(WebWxGetContactResponse response){

		logger.info("处理获取联系人Response开始...");
		
		if ( response.getBaseResponse() != null ) {
			
			if (response.getBaseResponse().getRet() == 0) {
				List<Contact> memberList = response.getMemberList();
				
				logger.info("联系人总数量" + memberList.size());

				if ( memberList != null ) {
					
					Map<String, String> renameFriendMap = new HashMap<>();
					
					for(Contact contact : memberList){
												
						// 公众号/服务号
						if ( (contact.getVerifyFlag() & 8) != 0) {
							
							InMemoryStorage.mpMap.put(contact.getNickName(), contact.clone());
							
							logger.info("-------------------------------------------");
							logger.info("公众号");
							logger.info("NickName : " + contact.getNickName());
							logger.info("UserName : " + contact.getUserName());
							logger.info(" ");
							
							continue;
						}
						// 特殊账号
						if (Constant.FILTER_USERS.contains(contact.getUserName())) {
							logger.info("-------------------------------------------");
							logger.info("特殊账号");
							logger.info("NickName : " + contact.getNickName());
							logger.info("UserName : " + contact.getUserName());
							logger.info(" ");							
							
							continue;
						}
						// 微信群
						if (contact.getUserName().startsWith("@@")) {

							if(StringUtils.isNotBlank(contact.getNickName())){
								
								boolean found = false;
								String nickName = contact.getNickName();
								
								for(Map.Entry<String, Contact> entry : InMemoryStorage.groupMap.entrySet()){
									if(contact.getUserName().equals(entry.getValue().getUserName())){
										found = true;
										break;
									}						
								}
								
								if(!found){
									InMemoryStorage.groupMap.put(nickName, contact.clone());
								}
								
								if(nickName.contains("减肥")){
									if(!InMemoryStorage.gymGroupList.contains(nickName)){
										InMemoryStorage.gymGroupList.add(nickName);
									}
								}
								
								logger.info("-------------------------------------------");
								logger.info("微信群");
								logger.info("NickName : " + contact.getNickName());
								logger.info("UserName : " + contact.getUserName());
								logger.info(" ");								
							}
							
							continue;
						}
						// 自己  
						if (contact.getUserName().equals(WxService.user.getUserName())) {
							logger.info("-------------------------------------------");
							logger.info("自己");
							logger.info("NickName : " + contact.getNickName());
							logger.info("UserName : " + contact.getUserName());
							logger.info("Alias    : " + contact.getAlias());
							logger.info(" ");
							
							continue;
						}

						// 好友		
						
						boolean found = false;
						String nickName = contact.getNickName();
						
						for(Map.Entry<String, Contact> entry : InMemoryStorage.friendMap.entrySet()){
							if(contact.getUserName().equals(entry.getValue().getUserName())){
								
								found = true;
								
								if(!nickName.equals(entry.getKey())){
									//好友改昵称了
									String oldName = entry.getKey();
									String newName = nickName;
									
									logger.info("--好友昵称修改了"
											+ " UserName: " + contact.getUserName()
											+ " 原来名字: [" + oldName + "]"
											+ " 新的名字: [" + newName + "]");
									
									renameFriendMap.put(oldName, newName);
								}
								break;
							}
						}
						
						if(!found){
							InMemoryStorage.friendMap.put(contact.getNickName(), contact.clone());
						}							
						
						logger.info("-------------------------------------------");
						logger.info("好友");
						logger.info("NickName : " + contact.getNickName());
						logger.info("UserName : " + contact.getUserName());
						logger.info("Alias    : " + contact.getAlias());
						logger.info(" ");
						
					}		
					
					for(Map.Entry<String, String> entry : renameFriendMap.entrySet()){
												
						String oldFriendName = entry.getKey();
						String newFriendName = entry.getValue();
						
						Contact contact = InMemoryStorage.friendMap.get(oldFriendName).clone();
						contact.setNickName(newFriendName);
						
						InMemoryStorage.friendMap.put(newFriendName, contact);
						InMemoryStorage.friendMap.remove(oldFriendName);

						updateDataBaseDueToFriendNameChanged(oldFriendName, newFriendName);

						if(InMemoryStorage.needToReloadQuartzAndStartScheduler){
							
							logger.info("重新loadQuartzAndStartScheduler");
							
							InMemoryStorage.needToReloadQuartzAndStartScheduler = false;
							
							boolean loadQuartzOK = false;
							if(LogicProcess.loadQuartzAndStartScheduler()){
								if(LogicProcess.pauseJobsDueToConfig()){
									loadQuartzOK = true;
								}								
							}
							
							if(!loadQuartzOK){
								for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){
									task.getValue().setTaskStatus(ScheduledTaskItem.UNKNOWN);
								}
							}						
						}
						
						updateMainFrameScheduledTaskInfo();
						updateMainFrameWelcomeMsgInfo();
						updateMainFrameAutoReplyInfo();
					}
					
					updateMainFrameFriendInfo();
				}	
			}
		}
		
		logger.info("处理获取联系人Response结束");

	}
	
	public static void handleBatchGetContactResponse(WebWxBatchGetContactResponse response){		

		logger.info("处理获取联系人详情Response开始...");

		if(response.getBaseResponse() != null){
			if(response.getBaseResponse().getRet() == 0){

				StringBuilder sb = new StringBuilder();

				Map<String, String> renameGroupMap = new HashMap<>();
				
				for(Contact contact : response.getContactList()){

//					if(StringUtils.isBlank(contact.getNickName())){
//
//						for(Map.Entry<String, Contact> entry : InMemoryStorage.groupMap.entrySet()){
//							if(entry.getValue().getUserName().equals(contact.getUserName())){
//								entry.getValue().setMemberCount(0);
//								entry.getValue().setMemberList(null);
//								logger.info("您已不在微信群[{}]中", entry.getKey());
//								break;
//							}
//						}
//						continue;
//					}

					if(contact.getUserName().startsWith("@@")){		
						//返回来的是微信群的信息

						boolean found = false;

						for(Map.Entry<String, Contact> entry : InMemoryStorage.groupMap.entrySet()){

							if(contact.equals(entry.getValue())){
								
								found = true;
								
								if(StringUtils.isBlank(contact.getNickName())){
									entry.getValue().setMemberCount(0);
									entry.getValue().setMemberList(null);
									logger.info("您已不在微信群[{}]中", entry.getKey());	
									continue;
								}
								
								if(contact.getNickName().equals(entry.getKey())){
		
									long oldNumber = entry.getValue().getMemberCount();
									long newNumber = contact.getMemberCount();
	
									logger.info("返回微信群[{}]信息，该群在groupMap中已有记录", entry.getKey());				
									logger.info("--该群原有成员数为： " + entry.getValue().getMemberCount());
									logger.info("--本次返回成员数为： " + contact.getMemberCount());	
	
									if(newNumber < oldNumber){
										//有人退群
	
										sb.append("[").append(entry.getKey()).append("]有成员退群或被移出，他们是：\r");
	
										List<Contact> removeList = new ArrayList<>();
	
										for(Contact member : entry.getValue().getMemberList()){
											if(!contact.getMemberList().contains(member)){
												removeList.add(member);
												sb.append(member.getNickName()).append("\r");
												logger.info("[{}]已退出或被移出群[{}]", member.getNickName(), entry.getKey());
											}
										}
	
										entry.getValue().getMemberList().removeAll(removeList);
									}										
	
									if(entry.getValue() == null){
										entry.setValue(new Contact());
									}
	
									if(entry.getValue().getMemberList() == null){
										List<Contact> memberListNew = new ArrayList<>();
										entry.getValue().setMemberList(memberListNew);
									}
	
									//entry.getValue().setNickName(contact.getNickName());
									//entry.getValue().setUserName(contact.getUserName());
									entry.getValue().setChatRoomId(contact.getChatRoomId());
									entry.getValue().setEncryChatRoomId(contact.getEncryChatRoomId());
									entry.getValue().setMemberCount(contact.getMemberCount());
	
									for(Contact member : contact.getMemberList()){
	
										//调用contains需要重写Contact类的equals方法才能正确的判断是否包含
										if(!entry.getValue().getMemberList().contains(member)){
											//新的群成员
											entry.getValue().getMemberList().add(member.clone());
	
											logger.info("--获得一个新成员 "
													+ " AttrStatus: " + member.getAttrStatus()
													+ " Uin: " + member.getUin()
													+ " DisplayName: " + member.getDisplayName()
													+ " Alias: " + member.getAlias()
													+ " UserName: " + member.getUserName()
													+ " NickName: [" + member.getNickName() + "]");													
										}else{
											//原有成员，检查是否修改了昵称，是的话更新昵称	
											for(Contact existMember : entry.getValue().getMemberList()){
												if(member.getUserName().equals(existMember.getUserName())){											
													if(!member.getNickName().equals(existMember.getNickName())){
														logger.info("--原有成员修改昵称"
																+ " UserName: " + member.getUserName()
																+ " 原来NickName: [" + existMember.getNickName() + "]"
																+ " 新的NickName: [" + member.getNickName() + "]");
	
														sb.append("[").append(entry.getKey()).append("]有成员修改昵称，旧昵称是[")
														.append(existMember.getNickName()).append("]\r新昵称是[").append(member.getNickName()).append("]\r");													
	
														//更新打卡记录
														updateSignInRecordDueToNickNameChanged(entry.getKey(), existMember.getNickName(), member.getNickName(), member.getAttrStatus());
	
														//更新昵称
														existMember.setNickName(member.getNickName());														
	
													}													
	
													break;
												}
											}										
										}
									}					
								}else{
									
									//群名字修改了
									
									String oldGroupName = entry.getKey();
									String newGroupName = contact.getNickName();
									
									logger.info("--群名字修改了"
											+ " UserName: " + contact.getUserName()
											+ " 原来名字: [" + oldGroupName + "]"
											+ " 新的名字: [" + newGroupName + "]");
									
									renameGroupMap.put(oldGroupName, newGroupName);
									
								}
							}

						}

						if(!found){
							//返回的群信息不在InMemoryStorage.groupMap中，新增一个记录到groupMap
							InMemoryStorage.groupMap.put(contact.getNickName(), contact.clone());

							logger.info("返回微信群[{}]信息，该群在groupMap中没有记录", contact.getNickName());
							logger.info("--该群成员数为： " + contact.getMemberCount());

							for(Contact member : contact.getMemberList()){

								//调用contains需要重写Member类的equals方法才能正确的判断是否包含
								logger.info("--获得一个新成员 "
										+ " AttrStatus: " + member.getAttrStatus()
										+ " Uin: " + member.getUin()
										+ " DisplayName: " + member.getDisplayName()
										+ " Alias: " + member.getAlias()
										+ " UserName: " + member.getUserName()
										+ " NickName: [" + member.getNickName() + "]");													
							}						
						}																		
					}					
				}
				
				for(Map.Entry<String, String> entry : renameGroupMap.entrySet()){
					
					String oldGroupName = entry.getKey();
					String newGroupName = entry.getValue();
					
					Contact contact = InMemoryStorage.groupMap.get(oldGroupName).clone();
					contact.setNickName(newGroupName);
					
					InMemoryStorage.groupMap.put(newGroupName, contact);
					InMemoryStorage.groupMap.remove(oldGroupName);
					
					updateDataBaseDueToGroupNameChanged(oldGroupName, newGroupName);

					if(InMemoryStorage.needToReloadQuartzAndStartScheduler){
						
						logger.info("重新loadQuartzAndStartScheduler");
						
						InMemoryStorage.needToReloadQuartzAndStartScheduler = false;
						
						boolean loadQuartzOK = false;
						if(LogicProcess.loadQuartzAndStartScheduler()){
							if(LogicProcess.pauseJobsDueToConfig()){
								loadQuartzOK = true;
							}								
						}
						
						if(!loadQuartzOK){
							for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){
								task.getValue().setTaskStatus(ScheduledTaskItem.UNKNOWN);
							}
						}						
					}
						
					updateMainFrameAutoReplyInfo();
					updateMainFrameScheduledTaskInfo();
					updateMainFrameWelcomeMsgInfo();
				}
								
				updateMainFrameGroupInfo();

				//将群信息变动情况发给已注册的接收者
				if(StringUtils.isNoneBlank(sb.toString())){
					for(String receiver : InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList()){
						if(InMemoryStorage.friendMap.get(receiver) != null){
							WxService.sendTextMsg(sb.toString(), InMemoryStorage.friendMap.get(receiver).getUserName());												
						}
					}
				}
			}
		}	
		logger.info("处理联系人详情Response结束");
	}

	
	/**
	 * 处理群里面来的文字消息
	 * @throws IOException 
	 */
	
	public static void processTextMsgFromGroup(String groupUserName, String content) throws IOException{
		
		String groupNickName = InMemoryStorage.findGroupNickName(groupUserName);
		
		if(groupNickName == null){
			
			logger.info("通过groupUserName找不到groupNickName, 发送get batch contact request重新同步group信息");
			
			updateGroupData(groupUserName);
			
			//再次检查是否能得到groupNickName
			groupNickName = InMemoryStorage.findGroupNickName(groupUserName);
		}
		
		if(groupNickName != null){
			logger.info("通过groupUserName找到groupNickName");
			logger.info("群名字： " + groupNickName);

			if(!InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(groupNickName)){
				logger.info("来自不受机器人控制的微信群,不处理");
				return;
			}
			
			logger.info("来自受机器人控制的微信群,继续处理...");
			
			String[] contentParts = content.split(":<br/>");
			String senderUserName = contentParts[0];
			String realContent = StringUtils.trimToEmpty(contentParts[1]);					
			String senderNickName = InMemoryStorage.findSenderNickName(groupNickName, senderUserName);
			long attrStatus = InMemoryStorage.findSenderAttrStatusName(groupNickName, senderUserName);
					
			if(senderNickName == null){

				//senderNickName没找到，有可能这是个新加入群的成员，重新发送get batch contact request同步group信息

				logger.info("senderNickName没找到，有可能这是个新加入群的成员，重新发送get batch contact request重新同步group信息...");

				updateGroupData(groupUserName);
				
				//再次检查是否能得到senderNickName
				senderNickName = InMemoryStorage.findSenderNickName(groupNickName, senderUserName);

			}

			if(senderNickName != null){
				
				logger.info("senderNickName找到，发送者是：" + senderNickName);
				logger.info("消息内容是： " + realContent);
				
				//支持形如： "{@阿童木}{  }打卡{啦}{[微笑]}{  }{@阿童木}" 的打卡输入，大括号内为可选输入，空格可以多个，{啦}为任意某个字符，{[强]}或者{[微笑]}为表情符
				StringBuilder sb = new StringBuilder();
				sb.append("(@").append(WxService.user.getNickName()).append(")?(.)?(\\s)*")
				  .append("打卡(.)?(\\[([\u4e00-\u9fa5]){1,2}\\])?(\\s)*").append("(@").append(WxService.user.getNickName()).append(")?(.)?");
											
				if(realContent.matches(sb.toString()) 
			       && !realContent.contains("?") 
			       && !realContent.contains("？")
			       && !realContent.contains("如何")
			       && !realContent.contains("在那")
			       && !realContent.contains("那里")
			       && !realContent.contains("在哪")
			       && !realContent.contains("哪里")
			       && !realContent.contains("为什么")
			       && !realContent.contains("为啥")
			       && !realContent.contains("怎么")){
					
					logger.info("收到打卡请求，进入打卡处理...");
					
					processSignIn(groupUserName, groupNickName, senderNickName, attrStatus);
				
				}else if(realContent.contains("打卡") && (
					       realContent.contains("?") 
					    || realContent.contains("？")
						|| realContent.contains("如何")
						|| realContent.contains("在那")
						|| realContent.contains("那里")
						|| realContent.contains("在哪")
						|| realContent.contains("哪里")
						|| realContent.contains("为什么")
						|| realContent.contains("为啥")
						|| realContent.contains("怎么")) ){
					
					//StringBuilder sb1 = new StringBuilder();
					//sb1.append("@").append(senderNickName).append(" 每天陪孩子阅读后就可以打卡，做个记录同时也是对自己的督促，坚持亲子阅读。\r\n")
					//.append("打卡只需要在群里输入打卡两个字就可以啦，").append(WxService.user.getNickName()).append("会帮您记录哒。");
					
					//WxService.sendTextMsg(sb1.toString() , groupUserName);
					
				}else if( realContent.startsWith("问题：") || realContent.startsWith("问题:") ||
						  realContent.startsWith("问题 ：") || realContent.startsWith("问题 :") ||
						  realContent.startsWith("提问：") || realContent.startsWith("提问:") ||
						  realContent.startsWith("提问 ：") || realContent.startsWith("提问 :")  ){
					
					logger.info("收到问题，进入搜集问题处理...");
					
					if(!InMemoryStorage.gymGroupList.contains(groupNickName)){
						processQuestionCollection(realContent,
								                  groupUserName, groupNickName, senderNickName);						
					}			        				       			        
				}else if(realContent.equals("<image>")){
					return;
				}else{
					
					Map<String, AutoReplyItem> map = InMemoryStorage.autoReplyEntity.getMap();
					
					for(String key : map.keySet()){
						
						if(realContent.matches(key)){					
							logger.info("关键字匹配成功，开始自动回复");
							
							AutoReplyItem item = map.get(key);
							
							if(item.getStatus() == AutoReplyItem.ENABLED){
								if(item.getGroupList().contains(groupNickName)){
									if(!item.getExcludedUserList().contains(senderNickName)){
										String text = item.getTextList().get(0).replace("<sender>", senderNickName);
										WxService.sendTextMsg(text, groupUserName);
										text = item.getTextList().get(1).replace("<sender>", senderNickName);
										WxService.sendTextMsg(text, groupUserName);
										WxService.sendImgMsg(item.getImageList().get(0), groupUserName);
									}								
								}								
							}
							
							break;
						}
					}

					
				}
			}else{
				logger.info("发消息用户的Nick Name未找到");
			}							
		}else{
			logger.info("来自不受机器人受理的微信群，不处理");
		}			
	}	
	
	
	/**
	 * 处理来自朋友的文字消息
	 * @throws IOException 
	 */
	
	public static void processTextMsgFromFriend(String fromUserName, String content) throws IOException{

		if( Constant.FILTER_USERS.contains(fromUserName) ){
			logger.info("特殊账号发来消息，不处理");
			return;
		}

		String senderNickName = InMemoryStorage.findSenderNickName(fromUserName);

		if(senderNickName == null){
			logger.info("非好友发来消息，不处理");
			return;
		}

		logger.info("好友[{}]发来消息", senderNickName);
		logger.info("消息内容：" + content);

		//只回复管理员发来的控制消息

		if( InMemoryStorage.userGroupCtrlEntity.getAdminList().contains(senderNickName)){

			if(content.equals("帮助")){

				StringBuilder sb = new StringBuilder();
				sb.append("阿童木可以识别的命令有：\r")
				.append("群编号\r")
				.append("欢迎\r")
				.append("打卡记录\r")
				.append("接收通知\r")
				.append("取消接收通知\r");

				WxService.sendTextMsg(sb.toString(), fromUserName);

			}else if(content.equals("群编号")){

				StringBuilder sb = new StringBuilder();

				for(int i = 0; i < InMemoryStorage.userGroupCtrlEntity.getGroupList().size(); i++){			
					//群编号从1开始
					sb.append(i + 1).append(" ").append(InMemoryStorage.userGroupCtrlEntity.getGroupList().get(i)).append("\r");
				}							
				WxService.sendTextMsg(sb.toString(), fromUserName);
			}else if(content.startsWith("欢迎")){

				if(StringUtils.trimToEmpty(content).equals("欢迎")){
					WxService.sendTextMsg("欢迎后面要接群编号", fromUserName);
					return;
				}

				String code = StringUtils.trimToEmpty(content.replace("欢迎", ""));
				
				if(StringUtils.isNoneBlank(code)){
				    
				    int number = 0;
				    
				    try{
	                    number = Integer.parseInt(code);
				    }catch(NumberFormatException e) {
	                    WxService.sendTextMsg("欢迎后面要接群编号", fromUserName);
	                    return;				        
				    }

					if( ( number <= InMemoryStorage.userGroupCtrlEntity.getGroupList().size() ) && 
							( number >= 1) ){

						String groupNickName = InMemoryStorage.userGroupCtrlEntity.getGroupList().get(Integer.parseInt(code)-1);						

						WelcomeMsgItem welcomeMsgItem = findWelcomeMsgItem(groupNickName);

						if(welcomeMsgItem != null){
						    if(welcomeMsgItem.getMsgStatus() == WelcomeMsgItem.ENABLED){
	                            sendWelcomeMsg(groupNickName, InMemoryStorage.newMemberMap.get(groupNickName));

	                            if(InMemoryStorage.newMemberMap.get(groupNickName) != null){
	                                InMemoryStorage.newMemberMap.get(groupNickName).clear();
	                            }

	                            WxService.sendTextMsg("欢迎消息发到[" + groupNickName + "]啦", fromUserName);						        
						    }else{
                                WxService.sendTextMsg("[" + groupNickName + "] 的欢迎消息已停用", fromUserName);                           

                          }					
						}else{
							WxService.sendTextMsg("[" + groupNickName + "] 木有配置欢迎消息喔", fromUserName);							
						}						

					}else{
						String endNo = String.valueOf( InMemoryStorage.userGroupCtrlEntity.getGroupList().size() );
						WxService.sendTextMsg("群编号必须大于等于1并且小于等于" + endNo + "，请重新输入", fromUserName);	

						StringBuilder sb = new StringBuilder();

						for(int i = 0; i < InMemoryStorage.userGroupCtrlEntity.getGroupList().size(); i++){			
							//群编号从1开始
							sb.append("群编号:\r");
							sb.append(i + 1).append(" ").append(InMemoryStorage.userGroupCtrlEntity.getGroupList().get(i)).append("\r");
						}							
						WxService.sendTextMsg(sb.toString(), fromUserName);
					}		
				}			
			}else if(content.startsWith("打卡记录")){

				if(StringUtils.trimToEmpty(content).equals("打卡记录")){
					WxService.sendTextMsg("打卡记录后面要接群编号", fromUserName);
					return;
				}

                String code = StringUtils.trimToEmpty(content.replace("打卡记录", ""));
                
				if(StringUtils.isNoneBlank(code)){

                    int number = 0;
                    
                    try{
                        number = Integer.parseInt(code);
                    }catch(NumberFormatException e) {
                        WxService.sendTextMsg("打卡记录后面要接群编号", fromUserName);
                        return;                     
                    }
                    
					if( ( number <= InMemoryStorage.userGroupCtrlEntity.getGroupList().size() ) && 
							( number >= 1) ){

						String groupNickName = InMemoryStorage.userGroupCtrlEntity.getGroupList().get(Integer.parseInt(code)-1);						

						String signInRecord = LogicProcess.getSignInRecord(groupNickName);
						if(!signInRecord.isEmpty()){
							WxService.sendTextMsg(groupNickName + "打卡记录：", fromUserName);
							WxService.sendTextMsg(signInRecord, fromUserName);
						}else{
							WxService.sendTextMsg(groupNickName + "没有打卡记录", fromUserName);
						}						

					}else{
						String endNo = String.valueOf( InMemoryStorage.userGroupCtrlEntity.getGroupList().size() );
						WxService.sendTextMsg("群编号必须大于等于1并且小于等于" + endNo + "，请重新输入", fromUserName);	

						StringBuilder sb = new StringBuilder();

						for(int i = 0; i < InMemoryStorage.userGroupCtrlEntity.getGroupList().size(); i++){			
							//群编号从1开始
							sb.append("群编号:\r");
							sb.append(i + 1).append(" ").append(InMemoryStorage.userGroupCtrlEntity.getGroupList().get(i)).append("\r");
						}							
						WxService.sendTextMsg(sb.toString(), fromUserName);
					}		
				}
			}else if(content.equals("家长问题")){						
				//				String question = FileUtil.read(Constant.questionFile, Constant.encoding);
				//				if(StringUtils.isNoneBlank(question)){
				//					WxService.sendTextMsg(question, fromUserName);		
				//				}else{
				//					WxService.sendTextMsg("目前还没有问题", fromUserName);		
				//				}
			}else if(content.equals("接收通知")){
				addFriendToNoticeReceiverList(senderNickName);
				WxService.sendTextMsg("好的，收编群信息变化会有通知", fromUserName);
				logger.info("[{}]将接收所有收编群的信息变化通知", senderNickName);

			}else if(content.equals("取消接收通知")){
				removeFriendFromNoticeReceiverList(senderNickName);
				WxService.sendTextMsg("好的，不会再发收编群信息变化通知", fromUserName);
				logger.info("[{}]将不再接收所有收编群的信息变化通知", senderNickName);

			}else{
				if(InMemoryStorage.allowFriendAutoReply){
					try{
						String ans = robot.talk(content);	
						WxService.sendTextMsg(ans, fromUserName);						
					}catch(Exception e){
						logger.info("茉莉机器人解析出错");
					}					
				}
			}			
		}else{
			if(InMemoryStorage.allowFriendAutoReply){
				try{
					String ans = robot.talk(content);	
					WxService.sendTextMsg(ans, fromUserName);						
				}catch(Exception e){
					logger.info("茉莉机器人解析出错");
				}				
			}
		}
	}

	/**
	 * 处理来自微信群的图片消息
	 */
	
	public static void processImgMsgFromGroup(String msgId, String fromUserName, String content){
		
/*		String imgDir = Constant.config.get("app.img_path");
		FileKit.createDir(imgDir, false);
		try{
			String imgUrl = WechatMeta.base_uri + "/webwxgetmsgimg?MsgID=" + msgId + "&skey=" + WechatMeta.skey + "&type=slave";
			//保存收到的图片
			HttpRequest.get(imgUrl).header("Cookie", WechatMeta.cookie).receive(new File(imgDir + "/" + msgId+".jpg"));					
		}catch(Exception e){
			logger.info("获取图片时发生异常");
		}*/

		String[] contentParts = content.split(":<br/>");
		String senderUserName = contentParts[0];
		String groupNickName = InMemoryStorage.findGroupNickName(fromUserName);
		

		if(groupNickName == null){
			logger.info("groupNickName找不到，尝试更新group信息");
			updateGroupData(fromUserName);
			
			//再次尝试获取groupNickName
			logger.info("更新group信息完毕，再次尝试获取groupNickName");
			groupNickName = InMemoryStorage.findGroupNickName(fromUserName);
		}
		
		if(groupNickName !=null ){
			logger.info("groupNickName获取成功");
			logger.info("群名字： " + groupNickName);
			
			if(!InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(groupNickName)){
				logger.info("来自不受机器人控制的微信群,不处理");
				return;
			}
			
			logger.info("来自受机器人控制的微信群,继续处理...");
			
			String senderNickName = InMemoryStorage.findSenderNickName(groupNickName, senderUserName);
	
			if(senderNickName == null){
				logger.info("senderNickName找不到，尝试更新group信息");
				updateGroupData(fromUserName);
				
				//再次尝试获取senderNickName
				logger.info("再次尝试获取senderNickName");
				senderNickName = InMemoryStorage.findSenderNickName(groupNickName, senderUserName);
			}
						
			if(senderNickName != null){
				logger.info("senderNickName获取到");
				
				Map<String, AutoReplyItem> map = InMemoryStorage.autoReplyEntity.getMap();
				
				if(map.keySet().contains("<image>")){
					
					AutoReplyItem item = map.get("<image>");
					
					if(item.getStatus() == AutoReplyItem.ENABLED){
						if(item.getGroupList().contains(groupNickName)){
							if(!item.getExcludedUserList().contains(senderNickName)){
								String text = item.getTextList().get(0).replace("<sender>", senderNickName);
								WxService.sendTextMsg(text, fromUserName);
								text = item.getTextList().get(1).replace("<sender>", senderNickName);
								WxService.sendTextMsg(text, fromUserName);
								WxService.sendImgMsg(item.getImageList().get(0), fromUserName);
							}						
						}						
					}
				}
			}else{
				logger.info("senderNickName仍然找不到");
			}
		}
	}

	//发送get batch request获取groupUserName对应微信群的详细信息，
	public static void updateGroupData(String groupUserName){

		List<Contact> contactList = new ArrayList<>();
		Contact contact = new Contact();
		contact.setUserName(groupUserName);		
		contactList.add(contact);		

		handleBatchGetContactResponse( WxService.getBatchContact( contactList, true ) );			
	}
	
	
	public static void reInitWx(){		
		logger.info("尝试重新调用wxInit、openStatusNotify和choiceSyncLine进行恢复");	
		WxService.webWxInit();
		WxService.webWxStatusNotify();
		WxService.chooseSyncLine();
	}
	
	public static void resetWeeklySignInRecord() throws IOException{

		Calendar calendar = Calendar.getInstance();	
		calendar.setTimeInMillis(System.currentTimeMillis());	
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		
		for(String group : InMemoryStorage.userGroupCtrlEntity.getSignInGroupList()){

			String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";

			String fileContent = FileUtil.read(fileName, Constant.encoding);

			if(fileContent == null){
				logger.info("微信群[ " + group + "]打卡文件不存在");
			}else{

				logger.info("微信群[" + group + "]打卡文件存在，开始解析");

				SignInRecord record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

				if(record != null){
					logger.info("解析成功，开始清除周打卡记录");

					if(record.getRecord() != null){
						for(SignInRecordItem recordItem: record.getRecord()){
							for(SignInDetail detail: recordItem.getDetail()){
								if(detail.getDay() == day){
									logger.info("周打卡记录清零前，用户[" + detail.getMember() + "]刚好在周一清零前打了一次卡");	
									detail.setTimes(1);
								}else{
									detail.setTimes(0);
									detail.setDay(-1);
								}
							}
						}
						
						String recordStr = JSON.toJSONString(record);
						FileUtil.write(fileName, recordStr, Constant.encoding, false);						
						logger.info("清除该群周打卡记录完成");												
					}					
				}
			}

		}
	}
	
	/**
	 * 处理群里面来的文字消息新人入群
	 * @throws IOException 
	 */
	
	private static void processNewMemberJoinMsg(String fromUserName, String content){
						
		String groupNickName = InMemoryStorage.findGroupNickName(fromUserName);
		
		if(InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(groupNickName)){
			
			//仅仅处理收编群的新人加入
			
			if(InMemoryStorage.newMemberMap.get(groupNickName) == null){
				InMemoryStorage.newMemberMap.put(groupNickName, new ArrayList<String>());
			}
			
			List<String> newMemberList = InMemoryStorage.newMemberMap.get(groupNickName);
									
			if(content.contains("扫描")){
				//通过扫描进群的用户，一个消息代表一个用户
				//Content:"" 明月"通过扫描"长剑"分享的二维码加入群聊"
				String newMember = StringUtils.trimToEmpty(Matchers.match("\"(.*)\"通过扫描", content));
							
				newMemberList.add(newMember);
				
				logger.info("微信群" + groupNickName + "通过扫描进来1个用户:" + newMember);
							
			}else if(content.contains("邀请")){
				
				//通过邀请进群的用户，一次可以邀请多个用户
				//被邀请的人以"、"分割
				//Content:""长剑"邀请"西门、破空"加入了群聊"
							
				String list[] = StringUtils.trimToEmpty( Matchers.match("邀请\"(.*)\"加入了群聊", content) ).split("、");
				
				StringBuilder sb = new StringBuilder();
	
				for(String member : list){
					newMemberList.add(member);
					sb.append("[").append(member).append("]");
				}
				
				logger.info("微信群" + groupNickName + "通过邀请进来" + list.length + "个用户: " + sb.toString());
			}
					
			int newNum = newMemberList.size();
			
			logger.info( "累计" + newNum + "个新成员入群");	
			
			WelcomeMsgItem welcomeMsgItem = findWelcomeMsgItem(groupNickName);
			
			if(welcomeMsgItem != null){
				if (newNum >= Long.valueOf(welcomeMsgItem.getThreshold())){
					//新加群的用户达到numNeedToSendWelcome，发送欢迎消息，并清除newMemberMap
					
					logger.info("发送入群必读信息");
					
					sendWelcomeMsg(groupNickName, newMemberList);
					//清除新人信息
					newMemberList.clear();
				}				
			}										
		}
							
		updateGroupData(fromUserName);
	}

	
	/**
	 * 显示二维码
	 * 
	 * @return
	 */
    public static boolean getQrCodeFilePath(String fileRealPath){
        
        WxService.getUuid();
        
        final File file = WxService.getQrCode(fileRealPath);
            
        if (null != file && file.exists() && file.isFile()) {
            return true;
        }else{
            return false;
        }
    }
	
	public static void closeQrWindow() {
	    	    
		File file = new File(WxService.getQrCodeFileRealPath());
		
		if(file.exists()){
		    file.delete();
		}
	}
	
	
	public static void start(){

		WxService.getPassport();		
		handleInitResponse( WxService.webWxInit() );
		WxService.webWxStatusNotify();
		
		//-----------------------------------
		//获取联系人列表
		
		long seq = 0;		
		
		do{
			WebWxGetContactResponse response = WxService.getContact(seq);
			handleGetContactResponse(response);
			seq = response.getSeq();			
		}while(seq != 0);
						
		//-----------------------------------
		//获取联系人详情
		ArrayList<Contact> originalList = new ArrayList<Contact>(InMemoryStorage.groupMap.values());
		int length = originalList.size();
		int getContactNumEachTime = 50;
		int pos = 0;

		logger.info("一共有{}个微信群", length);
		
		while(pos < length){
			List<Contact> list = new ArrayList<>();

			for(int i = 0; i < getContactNumEachTime; i++){
				list.add(originalList.get(pos++));
				if(pos == length){
					break;
				}
			}
			
			logger.info("准备获取从{}到{},一共{}个微信群的详情", pos - list.size(), pos - 1, list.size());
			handleBatchGetContactResponse( WxService.getBatchContact(list, true) );
		}

		//-----------------------------------
		createResourcesDir();
		printConfigParameters();	
		InMemoryStorage.printStorageInfo();				
	}
	
	
	private static void createResourcesDir(){
		
        File dir = new File(Constant.resourcesDir); 
        
		if (!dir.exists()) {  
		    dir.mkdirs();
		    logger.info("文件夹[{}]创建成功", Constant.resourcesDir);
		}else{
			logger.info("文件夹[{}]已存在，不需要创建", Constant.resourcesDir);
		}		
	}
	
	
	private static void printConfigParameters(){
		
		String para = null;
		
		para = Constant.limitInSigninRecordDisplay;
		logger.info("打卡统计显示的最多人数：" + para);
		
	}
		
	
	private static void updateMainFrameGroupInfo(){	

	}

	
	private static void updateMainFrameFriendInfo(){
		 
	}
	
	private static void updateMainFrameWelcomeMsgInfo(){

	}

	private static void updateMainFrameAutoReplyInfo(){

	}

	private static void updateMainFrameScheduledTaskInfo(){

	}
	
	public static boolean addGroupToUnderCtrlList(String groupUserName){
		
	    String group = InMemoryStorage.findGroupNickName(groupUserName);
	    
	    logger.info("准备收编group [{}]", group);
	    
	    if(group != null){
    		if(!InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(group)){
    			
    			InMemoryStorage.userGroupCtrlEntity.getGroupList().add(group);
    			
    			Gson gson = new Gson();
    
    			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
    			try {
                    FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);
                } catch (IOException e) {                    
                    logger.debug(Exceptions.getExceptionDetail(e));
                    return false;
                }
    
    			updateMainFrameGroupInfo();
    			
    		}else{
    		    logger.info("group [{}] 已经在收编群列表中", group);
    		}
	    }else{
	        return false;
	    }
	    
	    return true;
	}
	
	public static boolean removeGroupFromUnderCtrlList(String groupUserName){
		
	    String group = InMemoryStorage.findGroupNickName(groupUserName);
	        
	    logger.info("准备取消收编group [{}]", group);
	        
	    if(group != null){
    		if(InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(group)){
    			
    			InMemoryStorage.userGroupCtrlEntity.getGroupList().remove(group);
    			
    			//如果该群同时开启了打卡功能，需要将打卡功能也取消
    			if(InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().contains(group)){
    				InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().remove(group);
    			}
    			
    			Gson gson = new Gson();
    			
    			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
    			try {
                    FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);
                } catch (IOException e) {
                    logger.debug(Exceptions.getExceptionDetail(e));
                    return false;
                }
    
    			updateMainFrameGroupInfo();    
    		}else{
    		    logger.info("group [{}] 不在收编群列表中", group);
    		}
	    }else{
	        return false;
	    }
	
	    return true;
	}

	public static boolean addGroupToSignInList(String groupUserName){

	    String group = InMemoryStorage.findGroupNickName(groupUserName);

	    if(group != null){
    		//打卡群首先要是收编群
    		if(InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(group)){
    			if(!InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().contains(group)){
    				
    				InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().add(group);
    				
    				Gson gson = new Gson();
    	
    				String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
    				try {
                        FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);
                    } catch (IOException e) {
                        logger.debug(Exceptions.getExceptionDetail(e));
                        return false;
                    }  	
    				updateMainFrameGroupInfo();   				
    			}
    		}
	    }else{
	        return false;
	    }
		
	    return true;
	}
	
	public static boolean removeGroupFromSignInList(String groupUserName){

	    String group = InMemoryStorage.findGroupNickName(groupUserName);

	    if(group != null){
    		if(InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().contains(group)){
    
    			InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().remove(group);
    
    			Gson gson = new Gson();
    
    			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
    			try {
                    FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);
                } catch (IOException e) {
                    logger.debug(Exceptions.getExceptionDetail(e));
                    return false;
                }
    
    			updateMainFrameGroupInfo();
    
    		}
	    }else{
	        return false;
	    }
	    
	    return true;
			
	}

	public static void addFriendToAdminList(String friend) throws IOException{

		if(!InMemoryStorage.userGroupCtrlEntity.getAdminList().contains(friend)){

			InMemoryStorage.userGroupCtrlEntity.getAdminList().add(friend);
			
			//设为管理员默认接收通知
			if(!InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().contains(friend)){
				InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().add(friend);
			}

			Gson gson = new Gson();

			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
			FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);

			updateMainFrameFriendInfo();

			logger.info("更新InMemoryStorage.userGroupCtrlEntity和文件[{}]", Constant.userGroupCtrlFile);
		}		
	}
	
	public static void removeFriendFromAdminList(String friend) throws IOException{

		if(InMemoryStorage.userGroupCtrlEntity.getAdminList().contains(friend)){

			InMemoryStorage.userGroupCtrlEntity.getAdminList().remove(friend);
			
			//取消管理员的同时需要把接收通知取消
			if(InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().contains(friend)){
				InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().remove(friend);
			}
			
			Gson gson = new Gson();

			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
			FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);

			updateMainFrameFriendInfo();

			logger.info("更新InMemoryStorage.userGroupCtrlEntity和文件[{}]", Constant.userGroupCtrlFile);
		}			
	}

	public static void addFriendToNoticeReceiverList(String friend) throws IOException{

		if(!InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().contains(friend)){

			InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().add(friend);

			Gson gson = new Gson();

			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
			FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);

			updateMainFrameFriendInfo();

			logger.info("更新InMemoryStorage.userGroupCtrlEntity和文件[{}]", Constant.userGroupCtrlFile);
		}		
	}
	
	public static void removeFriendFromNoticeReceiverList(String friend) throws IOException{

		if(InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().contains(friend)){

			InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().remove(friend);

			Gson gson = new Gson();

			String json = gson.toJson(InMemoryStorage.userGroupCtrlEntity);
			FileUtil.write(Constant.userGroupCtrlFile, json, Constant.encoding, false);

			updateMainFrameFriendInfo();

			logger.info("更新InMemoryStorage.userGroupCtrlEntity和文件[{}]", Constant.userGroupCtrlFile);
		}			
	}
	
	public static void loadCustomConfig() throws IOException{

		Gson gson = new Gson();
		String content = null;
		
		//===========================================================
		//加载用户、微信群控制信息

		content = FileUtil.read(Constant.userGroupCtrlFile, Constant.encoding);

		if(content == null){
			logger.info("文件[{}]不存在，,不需要加载", Constant.userGroupCtrlFile);

		}else{

			logger.info("文件[{}]存在，内容是：{}", Constant.userGroupCtrlFile, content);

			InMemoryStorage.userGroupCtrlEntity = gson.fromJson(content, UserGroupCtrlEntity.class);

			logger.info("更新InMemoryStorage.userGroupCtrlEntity完毕");
		}

		//===========================================================
		//加载发送欢迎信息
		content = FileUtil.read(Constant.welcomeMsglFile, Constant.encoding);

		if(content == null){
			logger.info("文件[{}]不存在,不需要加载", Constant.welcomeMsglFile);

		}else{

			logger.info("文件[{}]存在，内容是：{}", Constant.welcomeMsglFile, content);

			InMemoryStorage.welcomeMsgEntity = gson.fromJson(content, WelcomeMsgEntity.class);

			logger.info("更新InMemoryStorage.welcomeMsgEntity完毕");
		}

		//===========================================================
		//加载自动回复

		content = FileUtil.read(Constant.autoReplyFile, Constant.encoding);

		if(content == null){
			logger.info("文件[{}]不存在,不需要加载", Constant.autoReplyFile);

		}else{

			logger.info("文件[{}]存在，内容是：{}", Constant.autoReplyFile, content);

			InMemoryStorage.autoReplyEntity = gson.fromJson(content, AutoReplyEntity.class);

			logger.info("更新InMemoryStorage.autoRespondEntity完毕");
		}

		//===========================================================
		//加载定时任务

		content = FileUtil.read(Constant.scheduledTaskFile, Constant.encoding);

		if(content == null){
			logger.info("文件[{}]不存在,不需要加载", Constant.scheduledTaskFile);

		}else{

			logger.info("文件[{}]存在，内容是：{}", Constant.scheduledTaskFile, content);

			InMemoryStorage.scheduledTaskEntity = gson.fromJson(content, ScheduledTaskEntity.class);

			logger.info("更新InMemoryStorage.scheduledTaskEntity完毕");
		}									
	}
	
	public static SignInDetail findSignInInfo(String group, String member) throws IOException{
		
		SignInDetail foundDetail = new SignInDetail();
		
		String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";
		
		String fileContent = FileUtil.read(fileName, Constant.encoding);

		SignInRecord record = null;

		if(fileContent != null){
			record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

			if(record != null){
				
				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(group)){

							for(SignInDetail detail: recordItem.getDetail()){

								if(detail.getMember().equals(member)){
									foundDetail = detail;
								}
							}
						}
					}
				}
			}		
		}
		
		return foundDetail;
	}
	
	public static SignInRecord findSignInInfo(String group) throws IOException{
		
		SignInRecord foundRecord = null;	
		
		String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";
		String fileContent = FileUtil.read(fileName, Constant.encoding);

		if(fileContent != null){
			SignInRecord record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

			if(record != null){
				
				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(group)){
							foundRecord = record;
						}
					}
				}
			}
		}
		
		return foundRecord;
	}
	
	public static boolean loadQuartzAndStartScheduler(){
		
		boolean flag = true;
		
		for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){			
			
		    flag = QuartzManager.addJob(task.getKey(), task.getValue());
			
			if(!flag){
				return flag;
			}
		}
		
		return QuartzManager.startScheduler();		
	}

    public static boolean removeAllJobs(){
        
        boolean flag = true;
        
        for(String jobName : InMemoryStorage.scheduledTaskEntity.getMap().keySet()){           
            
            flag = QuartzManager.removeJob(jobName);
            
            if(!flag){
                return flag;
            }
        }
        
        return flag;      
    }
    
	public static boolean pauseJobsDueToConfig(){
		
		boolean flag = true;
		
		for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){			
			
			if(task.getValue().getTaskStatus() == ScheduledTaskItem.PAUSE){
				flag = pauseJob(task.getKey());
				if(flag){
					logger.info("任务[{}]已暂停", task.getKey());
				}else{
					break;
				}
			}		
		}
		
		return flag;
	}
	
	
	public static boolean createOrModifyJob(String jobName, ScheduledTaskItem taskItem, boolean isCreate){
				
		if(!isCreate){
			//修改，先删除原来的job
			if(QuartzManager.removeJob(jobName)){
				InMemoryStorage.scheduledTaskEntity.getMap().remove(jobName);
			}else{
				return false;
			}
		}
		
		if(QuartzManager.addJob(jobName, taskItem)){
			InMemoryStorage.scheduledTaskEntity.getMap().put(jobName, taskItem);
			
			return saveScheduledTaskEntityToFile();
		}
		
		return false;		
	}

	public static boolean removeJob(String jobName){
				
		if(QuartzManager.removeJob(jobName)){
			InMemoryStorage.scheduledTaskEntity.getMap().remove(jobName);
						
			return saveScheduledTaskEntityToFile();
		}
		
		return false;		
	}

	public static boolean pauseJob(String jobName){

		ScheduledTaskItem taskItem = InMemoryStorage.scheduledTaskEntity.getMap().get(jobName);

		if(QuartzManager.pauseJob(jobName)){
			taskItem.setTaskStatus(ScheduledTaskItem.PAUSE);

			return saveScheduledTaskEntityToFile();
		}else{
			return false;
		}		
	}
	
	public static boolean resumeJob(String jobName){
				
		ScheduledTaskItem taskItem = InMemoryStorage.scheduledTaskEntity.getMap().get(jobName);
		
		if( taskItem.getTaskStatus() != ScheduledTaskItem.READY){
			if(QuartzManager.resumeJob(jobName)){
				taskItem.setTaskStatus(ScheduledTaskItem.READY);
				
				return saveScheduledTaskEntityToFile();
			}else{
				return false;
			}		
		}		
		return true;		
	}
	
	
	public static boolean resumeAllJobs(){
				
		for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){	
			
			if(task.getValue().getTaskStatus() != ScheduledTaskItem.READY){				
				if(QuartzManager.resumeJob(task.getKey())){
					task.getValue().setTaskStatus(ScheduledTaskItem.READY);
				}else{
					return false;
				}
			}
		}
		
		return saveScheduledTaskEntityToFile();				
	}
	
	public static boolean pauseAllJobs(){
		
		for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){	
			
			if(task.getValue().getTaskStatus() != ScheduledTaskItem.PAUSE){				
				if(QuartzManager.pauseJob(task.getKey())){
					task.getValue().setTaskStatus(ScheduledTaskItem.PAUSE);
				}else{
					return false;
				}
			}
		}

		return saveScheduledTaskEntityToFile();			
	}
	
	private static boolean saveScheduledTaskEntityToFile(){
		Gson gson = new Gson();
		String content = gson.toJson(InMemoryStorage.scheduledTaskEntity);
		
		try {
			FileUtil.write(Constant.scheduledTaskFile, content, Constant.encoding, false);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return false;
		}
		
		return true;
	}
	
	private static boolean isGroupHasSignInFunction(String group){
		
		return InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().contains(group);
	}
	
	private static void processMsgType10000(WebWxSyncResponse response){
		
		for(AddMsgListItem item : response.getAddMsgList()){
			String content = item.getContent();
			
//			if(content.contains("邀请你加入了群聊") || content.contains("你通过扫描二维码加入群聊")){
//				logger.info("您被邀请加入了某个群");
//				//机器人自己被加入了某个群
//				processJoinNewGroupMsg(response);
//			}else if(content.contains("加入了群聊") || content.contains("通过扫描")){
//				//机器人所在的群加入了新人
//				logger.info("您所在的某个群加入了新人");
//				processNewMemberJoinMsg(item.getFromUserName(), content);				
//			}else if(content.contains("你已添加了")){
//				//机器人添加了一个好友
//				logger.info("您添加了某个好友");
//				processNewFriendAddedMsg(response);
//			}	
					
			if(content.matches(".*邀请你加入了群聊.*") || content.matches(".*你通过扫描二维码加入群聊.*")){
				logger.info("您被邀请加入了某个群");
				//机器人自己被加入了某个群
				processJoinNewGroupMsg(response);
			}else if(content.matches(".*邀请.*加入了群聊") || content.matches(".*通过扫描.*分享的二维码加入群聊.*")){
				//机器人所在的群加入了新人
				logger.info("您所在的某个群加入了新人");
				processNewMemberJoinMsg(item.getFromUserName(), content);				
			}else if(content.matches(".*你已添加了.*")){
				//机器人添加了一个好友
				logger.info("您添加了某个好友");
				processNewFriendAddedMsg(response);
			}else if(content.matches(".*修改群名为.*")){
				//微信群改名
				logger.info("微信群改名了");
				updateGroupData(item.getFromUserName());
			}			
		}
	}
	
	private static void processJoinNewGroupMsg(WebWxSyncResponse response){
		
		if(response.getModContactCount() > 0){
			for(ModContactListItem item : response.getModContactList()){
				if(!InMemoryStorage.groupMap.keySet().contains(item.getNickName())){
					if(item.getUserName().startsWith("@@")){	
						Contact contactNew = new Contact();
						contactNew.setNickName(item.getNickName());
						contactNew.setNickName(item.getUserName());
						contactNew.setMemberCount(item.getMemberCount());
						
						if(item.getMemberCount() > 0){							
							List<Contact> memberListNew = new ArrayList<>();							
							for(Contact contact : item.getMemberList()){
								memberListNew.add(contact.clone());
							}							
							contactNew.setMemberList(memberListNew);
						}
						
						InMemoryStorage.groupMap.put(item.getNickName(), contactNew);						
					}
				}else{
					updateGroupData(item.getUserName());
				}
			}			
		}else{
			for(AddMsgListItem item : response.getAddMsgList()){
				updateGroupData(item.getFromUserName());
			}
		}	
	}

	private static void processNewFriendAddedMsg(WebWxSyncResponse response){
		
		if(response.getModContactCount() > 0){
			for(ModContactListItem item : response.getModContactList()){
				if(!InMemoryStorage.friendMap.keySet().contains(item.getNickName())){
					if(item.getUserName().startsWith("@") && !item.getUserName().startsWith("@@")){
						Contact contactNew = new Contact();
						contactNew.setNickName(item.getNickName());
						contactNew.setNickName(item.getUserName());
						contactNew.setSex(item.getSex());
						contactNew.setCity(item.getCity());
						contactNew.setProvince(item.getProvince());
				 											
						InMemoryStorage.friendMap.put(item.getNickName(), contactNew);	
						
						updateMainFrameFriendInfo();
					}					
				}
			}			
		}
	}
	
		
	public static boolean createOrModifyAutoReply(String keyName, AutoReplyItem item, boolean isCreate){
		
		if(!isCreate){
			//修改，先删除原来的msg
			InMemoryStorage.autoReplyEntity.getMap().remove(keyName);
		}
		
		InMemoryStorage.autoReplyEntity.getMap().put(keyName, item);
			
		return saveAutoReplyEntityToFile();		
	}
	
	public static boolean removeAutoReply(String keyName){
		
		InMemoryStorage.autoReplyEntity.getMap().remove(keyName);
						
		return saveAutoReplyEntityToFile();
		
	}

	public static boolean pauseAutoReply(String keyName){
				
		AutoReplyItem msgItem = InMemoryStorage.autoReplyEntity.getMap().get(keyName);
		
		if( msgItem.getStatus() != AutoReplyItem.DISABLED){
			
			msgItem.setStatus(AutoReplyItem.DISABLED);
				
			return saveAutoReplyEntityToFile();
		}
		
		return true;		
	}
	
	public static boolean resumeAutoReply(String keyName){
				
		AutoReplyItem msgItem = InMemoryStorage.autoReplyEntity.getMap().get(keyName);
		
		if( msgItem.getStatus() != AutoReplyItem.ENABLED){
			
			msgItem.setStatus(AutoReplyItem.ENABLED);
				
			return saveAutoReplyEntityToFile();
		}
		
		return true;
	}
	
	
	public static boolean resumeAllAutoReply(){
				
		for(Map.Entry<String, AutoReplyItem> entry : InMemoryStorage.autoReplyEntity.getMap().entrySet()){	
			
			if(entry.getValue().getStatus() != AutoReplyItem.ENABLED){				
				entry.getValue().setStatus(AutoReplyItem.ENABLED);
			}
		}
		
		return saveAutoReplyEntityToFile();				
	}
	
	public static boolean pauseAllAutoReply(){
		
		for(Map.Entry<String, AutoReplyItem> entry : InMemoryStorage.autoReplyEntity.getMap().entrySet()){	
			
			if(entry.getValue().getStatus() != AutoReplyItem.DISABLED){				
				entry.getValue().setStatus(AutoReplyItem.DISABLED);
			}
		}
		
		return saveAutoReplyEntityToFile();		
	}
	
	private static boolean saveAutoReplyEntityToFile(){
		Gson gson = new Gson();
		String content = gson.toJson(InMemoryStorage.autoReplyEntity);
		
		try {
			FileUtil.write(Constant.autoReplyFile, content, Constant.encoding, false);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return false;
		}
		
		return true;
	}

	public static WelcomeMsgItem findWelcomeMsgItem(String groupNickName){
		
		WelcomeMsgItem welcomeMsgItem = null;
		
		for(Map.Entry<String, WelcomeMsgItem> entry : InMemoryStorage.welcomeMsgEntity.getMap().entrySet()){
			if(entry.getValue().getGroupReceivers().contains(groupNickName)){
				welcomeMsgItem = entry.getValue();
			}
		}
		
		return welcomeMsgItem;
	}
	
	
	public static boolean createOrModifyWelcomeMsg(String msgName, WelcomeMsgItem msgItem, boolean isCreate){
		
		if(!isCreate){
			//修改，先删除原来的msg
			InMemoryStorage.welcomeMsgEntity.getMap().remove(msgName);
		}
		
		InMemoryStorage.welcomeMsgEntity.getMap().put(msgName, msgItem);
			
		return saveWelcomeMsgEntityToFile();		
	}
	
	public static boolean removeWelcomeMsg(String msgName){
		
		InMemoryStorage.welcomeMsgEntity.getMap().remove(msgName);
						
		return saveWelcomeMsgEntityToFile();
		
	}

	public static boolean pauseWelcomeMsg(String msgName){
				
		WelcomeMsgItem msgItem = InMemoryStorage.welcomeMsgEntity.getMap().get(msgName);
		
		if( msgItem.getMsgStatus() != WelcomeMsgItem.DISABLED){
			
			msgItem.setMsgStatus(WelcomeMsgItem.DISABLED);
				
			return saveWelcomeMsgEntityToFile();
		}
		
		return true;		
	}
	
	public static boolean resumeWelcomeMsg(String msgName){
				
		WelcomeMsgItem msgItem = InMemoryStorage.welcomeMsgEntity.getMap().get(msgName);
		
		if( msgItem.getMsgStatus() != WelcomeMsgItem.ENABLED){
			
			msgItem.setMsgStatus(WelcomeMsgItem.ENABLED);
				
			return saveWelcomeMsgEntityToFile();
		}
		
		return true;
	}
	
	
	public static boolean resumeAllWelcomeMsg(){
				
		for(Map.Entry<String, WelcomeMsgItem> msg : InMemoryStorage.welcomeMsgEntity.getMap().entrySet()){	
			
			if(msg.getValue().getMsgStatus() != WelcomeMsgItem.ENABLED){				
				msg.getValue().setMsgStatus(WelcomeMsgItem.ENABLED);
			}
		}
		
		return saveWelcomeMsgEntityToFile();				
	}
	
	public static boolean pauseAllWelcomeMsg(){
		
		for(Map.Entry<String, WelcomeMsgItem> msg : InMemoryStorage.welcomeMsgEntity.getMap().entrySet()){	
			
			if(msg.getValue().getMsgStatus() != WelcomeMsgItem.DISABLED){				
				msg.getValue().setMsgStatus(WelcomeMsgItem.DISABLED);
			}
		}
		
		return saveWelcomeMsgEntityToFile();		
	}
	
	private static boolean saveWelcomeMsgEntityToFile(){
		Gson gson = new Gson();
		String content = gson.toJson(InMemoryStorage.welcomeMsgEntity);
		
		try {
			FileUtil.write(Constant.welcomeMsglFile, content, Constant.encoding, false);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return false;
		}
		
		return true;
	}
	
	private static void updateSignInRecordDueToNickNameChanged(String group, String oldNickName, String newNickName, long attrStatus){
		
		//文件名为微信群名字+当前时间周数
		String fileName = Constant.signInFileDir + "打卡记录-" + group + ".txt";
		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		SignInRecord record = null;

		if(fileContent == null){
			logger.info("打卡记录文件还不存在，不需要更新");
			return;

		}else{
			logger.info("打卡记录文件已存在，从文件内容中解析出Record对象");

			record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

			if(record != null){
				boolean memberFound = false;

				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(group)){

							for(SignInDetail detail: recordItem.getDetail()){
								
								if(oldNickName.equals(detail.getMember())){
									logger.info("找到该用户的打卡记录，开始修改其昵称");
									memberFound = true;
									detail.setMember(newNickName);
									
									logger.info("用户 [" + oldNickName + "]在微信群[" + group + "]的打卡记录修改昵称为[" + newNickName + "]。开始记录到文件...");

									String recordStr = JSON.toJSONString(record);
									
									try {
										FileUtil.write(fileName, recordStr, Constant.encoding, false);
									} catch (IOException e) {
										logger.info(Exceptions.getExceptionDetail(e));
									}
									
									break;
								}
							}
						}

						if(memberFound){
							break;
						}
					}

				}else{
					logger.info("出错-打卡文件JSON解析出来Record对象内的record列表为空");
				}								
			}else{
				logger.info("出错-打卡文件JSON解析出来Record对象为空");
			}			
		}
	}
	
	private static void updateDataBaseDueToGroupNameChanged(String oldGroupName, String newGroupName){
			
		updateSignInFileDueToGroupNameChanged(oldGroupName, newGroupName);
		updateUserGroupCtrlFileDueToGroupNameChanged(oldGroupName, newGroupName);
		updateWelcomeMsglFileDueToGroupNameChanged(oldGroupName, newGroupName);
		updateAutoReplyFileDueToGroupNameChanged(oldGroupName, newGroupName);
		updateScheduledTaskFileDueToGroupNameChanged(oldGroupName, newGroupName);
		
		try {
			loadCustomConfig();
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
		}
	}
	
	
	private static void updateSignInFileDueToGroupNameChanged(String oldGroupName, String newGroupName){
		
		//文件名为微信群名字+当前时间周数
		String oldFileName = Constant.signInFileDir + "打卡记录-" + oldGroupName + ".txt";
		String newFileName = Constant.signInFileDir + "打卡记录-" + newGroupName + ".txt";
		
		//拷贝文件
		try {
			File srcFile = new File(oldFileName);
			File destFile = new File(newFileName);
			if(srcFile.exists()){
				FileUtils.copyFile(srcFile, destFile, false);
			}else{
				logger.info("打卡记录文件还不存在，不需要更新");
				return;
			}
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
		}
		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(newFileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		SignInRecord record = null;

		if(fileContent == null){
			logger.info("奇怪，拷贝后的打卡记录文件不存在，不需要更新");
			return;

		}else{
			logger.info("打卡记录文件已存在，拷贝为新文件名，并从新文件内容中解析出Record对象");

			record = JSON.parseObject(fileContent.toString(), SignInRecord.class); 

			if(record != null){
				if(record.getRecord() != null){
					for(SignInRecordItem recordItem: record.getRecord()){

						if(recordItem.getGroup().equals(oldGroupName)){
							logger.info("找到该群的打卡记录，开始修改群名字");
							recordItem.setGroup(newGroupName);
							
							logger.info("[" + oldGroupName + "]的打卡记录修改群名字为[" + newGroupName + "]。开始记录到文件...");

							String recordStr = JSON.toJSONString(record);
							
							try {
								FileUtil.write(newFileName, recordStr, Constant.encoding, false);
							} catch (IOException e) {
								logger.info(Exceptions.getExceptionDetail(e));
							}
							
							break;
						}
					}					

				}else{
					logger.info("出错-打卡文件JSON解析出来Record对象内的record列表为空");
				}								
			}else{
				logger.info("出错-打卡文件JSON解析出来Record对象为空");
			}			
		}
	}
	
	private static void updateUserGroupCtrlFileDueToGroupNameChanged(String oldGroupName, String newGroupName){
		
		String fileName = Constant.userGroupCtrlFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		UserGroupCtrlEntity userGroupCtrlEntity = null;

		if(fileContent == null){
			logger.info("userGroupCtrlFile不存在，不需要更新");
			return;

		}else{
			logger.info("userGroupCtrlFile已存在，从文件内容中解析出UserGroupCtrlEntity对象");

			userGroupCtrlEntity = JSON.parseObject(fileContent.toString(), UserGroupCtrlEntity.class); 

			if(userGroupCtrlEntity != null){
				if(userGroupCtrlEntity.getGroupList() != null){
					if(userGroupCtrlEntity.getGroupList().remove(oldGroupName)){
						userGroupCtrlEntity.getGroupList().add(newGroupName);
					}
				}
				
				if(userGroupCtrlEntity.getSignInGroupList() != null){
					if(userGroupCtrlEntity.getSignInGroupList().remove(oldGroupName)){
						userGroupCtrlEntity.getSignInGroupList().add(newGroupName);
					}
				}
						
				String recordStr = JSON.toJSONString(userGroupCtrlEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来UserGroupCtrlEntity对象为空");
			}			
		}
	}

	private static void updateWelcomeMsglFileDueToGroupNameChanged(String oldGroupName, String newGroupName){
		
		String fileName = Constant.welcomeMsglFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		WelcomeMsgEntity welcomeMsgEntity = null;

		if(fileContent == null){
			logger.info("welcomeMsglFile不存在，不需要更新");
			return;

		}else{
			logger.info("welcomeMsglFile已存在，从文件内容中解析出WelcomeMsgEntity对象");

			welcomeMsgEntity = JSON.parseObject(fileContent.toString(), WelcomeMsgEntity.class); 

			if(welcomeMsgEntity != null){
				
				for(Map.Entry<String, WelcomeMsgItem> entry : welcomeMsgEntity.getMap().entrySet()){
					if(entry.getValue().getGroupReceivers().remove(oldGroupName)){
						entry.getValue().getGroupReceivers().add(newGroupName);
					}
				}				
						
				String recordStr = JSON.toJSONString(welcomeMsgEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来WelcomeMsgEntity对象为空");
			}			
		}	
	}

	private static void updateAutoReplyFileDueToGroupNameChanged(String oldGroupName, String newGroupName){
		
		String fileName = Constant.autoReplyFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		AutoReplyEntity autoReplyEntity = null;

		if(fileContent == null){
			logger.info("autoReplyFile不存在，不需要更新");
			return;

		}else{
			logger.info("autoReplyFile已存在，从文件内容中解析出WelcomeMsgEntity对象");

			autoReplyEntity = JSON.parseObject(fileContent.toString(), AutoReplyEntity.class); 

			if(autoReplyEntity != null){
				
				for(Map.Entry<String, AutoReplyItem> entry : autoReplyEntity.getMap().entrySet()){
					if(entry.getValue().getGroupList().remove(oldGroupName)){
						entry.getValue().getGroupList().add(newGroupName);
					}
				}				
						
				String recordStr = JSON.toJSONString(autoReplyEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来AutoReplyEntity对象为空");
			}			
		}
	}
	
	private static void updateScheduledTaskFileDueToGroupNameChanged(String oldGroupName, String newGroupName){
		
		String fileName = Constant.scheduledTaskFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		ScheduledTaskEntity scheduledTaskEntity = null;

		if(fileContent == null){
			logger.info("scheduledTaskFile不存在，不需要更新");
			return;

		}else{
			logger.info("scheduledTaskFile已存在，从文件内容中解析出ScheduledTaskEntity对象");

			scheduledTaskEntity = JSON.parseObject(fileContent.toString(), ScheduledTaskEntity.class); 

			if(scheduledTaskEntity != null){
				
				for(Map.Entry<String, ScheduledTaskItem> entry : scheduledTaskEntity.getMap().entrySet()){
					if(entry.getValue().getCustomData().getGroupReceivers().remove(oldGroupName)){
						InMemoryStorage.needToReloadQuartzAndStartScheduler = true;
						entry.getValue().getCustomData().getGroupReceivers().add(newGroupName);
					}
				}				
						
				String recordStr = JSON.toJSONString(scheduledTaskEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来ScheduledTaskEntity对象为空");
			}			
		}	
	}


	private static void updateDataBaseDueToFriendNameChanged(String oldFriendName, String newFriendName){
		
		updateUserGroupCtrlFileDueToFriendNameChanged(oldFriendName, newFriendName);
		updateScheduledTaskFileDueToFriendNameChanged(oldFriendName, newFriendName);
		updateAutoReplyFileDueToFriendNameChanged(oldFriendName, newFriendName);
		
		try {
			loadCustomConfig();
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
		}
	}
	
	private static void updateUserGroupCtrlFileDueToFriendNameChanged(String oldFriendName, String newFriendName){
		
		String fileName = Constant.userGroupCtrlFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		UserGroupCtrlEntity userGroupCtrlEntity = null;

		if(fileContent == null){
			logger.info("userGroupCtrlFile不存在，不需要更新");
			return;

		}else{
			logger.info("userGroupCtrlFile已存在，从文件内容中解析出UserGroupCtrlEntity对象");

			userGroupCtrlEntity = JSON.parseObject(fileContent.toString(), UserGroupCtrlEntity.class); 

			if(userGroupCtrlEntity != null){
				if(userGroupCtrlEntity.getAdminList() != null){
					if(userGroupCtrlEntity.getAdminList().remove(oldFriendName)){
						userGroupCtrlEntity.getAdminList().add(newFriendName);
					}
				}
				
				if(userGroupCtrlEntity.getNoticeReceiverList() != null){
					if(userGroupCtrlEntity.getNoticeReceiverList().remove(oldFriendName)){
						userGroupCtrlEntity.getNoticeReceiverList().add(newFriendName);
					}
				}
						
				String recordStr = JSON.toJSONString(userGroupCtrlEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来UserGroupCtrlEntity对象为空");
			}			
		}	
	}

	private static void updateScheduledTaskFileDueToFriendNameChanged(String oldFriendName, String newFriendName){

		String fileName = Constant.scheduledTaskFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		ScheduledTaskEntity scheduledTaskEntity = null;

		if(fileContent == null){
			logger.info("scheduledTaskFile不存在，不需要更新");
			return;

		}else{
			logger.info("scheduledTaskFile已存在，从文件内容中解析出ScheduledTaskEntity对象");

			scheduledTaskEntity = JSON.parseObject(fileContent.toString(), ScheduledTaskEntity.class); 

			if(scheduledTaskEntity != null){
				
				for(Map.Entry<String, ScheduledTaskItem> entry : scheduledTaskEntity.getMap().entrySet()){
					if(entry.getValue().getCustomData().getFriendReceivers().remove(oldFriendName)){
						InMemoryStorage.needToReloadQuartzAndStartScheduler = true;
						entry.getValue().getCustomData().getFriendReceivers().add(newFriendName);
					}
				}				
						
				String recordStr = JSON.toJSONString(scheduledTaskEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来ScheduledTaskEntity对象为空");
			}			
		}	
	}
	
	private static void updateAutoReplyFileDueToFriendNameChanged(String oldFriendName, String newFriendName){

		String fileName = Constant.autoReplyFile;		
		String fileContent = null;
		
		try {
			fileContent = FileUtil.read(fileName, Constant.encoding);
		} catch (IOException e) {
			logger.info(Exceptions.getExceptionDetail(e));
			return;
		}

		AutoReplyEntity autoReplyEntity = null;

		if(fileContent == null){
			logger.info("autoReplyFile不存在，不需要更新");
			return;

		}else{
			logger.info("autoReplyFile已存在，从文件内容中解析出AutoReplyEntity对象");

			autoReplyEntity = JSON.parseObject(fileContent.toString(), AutoReplyEntity.class); 

			if(autoReplyEntity != null){
				
				for(Map.Entry<String, AutoReplyItem> entry : autoReplyEntity.getMap().entrySet()){
					if(entry.getValue().getExcludedUserList().remove(oldFriendName)){
						entry.getValue().getExcludedUserList().add(newFriendName);
					}
				}				
						
				String recordStr = JSON.toJSONString(autoReplyEntity);
				
				try {
					FileUtil.write(fileName, recordStr, Constant.encoding, false);
				} catch (IOException e) {
					logger.info(Exceptions.getExceptionDetail(e));
				}
				
			}else{
				logger.info("出错-JSON解析出来AutoReplyEntity对象为空");
			}			
		}	
	}
	
	public static void initDataInWxServiceAndInMemoryStorage(){
	    
	    WxService.init();
	    InMemoryStorage.init();
	}
	
	public static List<GroupVo> getGroupList(boolean requireFullList){
        	    
	    List<GroupVo> groupList = new ArrayList<>();
 
        int groupNo = 1;
    
        List<String> list = InMemoryStorage.userGroupCtrlEntity.getGroupList();
        
        Collections.sort(list);
        
        // 填充已收编群数据     
        for(String group : list){
            
            if(InMemoryStorage.groupMap.keySet().contains(group)){
                
                GroupVo groupVo = new GroupVo();

                groupVo.setNo(String.valueOf(groupNo++));
                groupVo.setName(EmojiConverter.convert(InMemoryStorage.groupMap.get(group).getNickName()));
                groupVo.setNum(String.valueOf(InMemoryStorage.groupMap.get(group).getMemberCount()));  
                groupVo.setUnderCtrl(true);
                if(InMemoryStorage.userGroupCtrlEntity.getSignInGroupList().contains(group)){
                    //打卡功能
                    groupVo.setSignIn(true);
                }else{
                    groupVo.setSignIn(false);
                }
                
                //groupVo.setUserName(InMemoryStorage.groupMap.get(group).getUserName());
                groupVo.setUserName(SimpleCipher.encrypt(InMemoryStorage.groupMap.get(group).getUserName()));
                
                groupList.add(groupVo);
            }
        }

        if(requireFullList){
            // 填充未收编群数据
            for(Map.Entry<String, Contact> entry : InMemoryStorage.groupMap.entrySet()){
                
                if(!InMemoryStorage.userGroupCtrlEntity.getGroupList().contains(entry.getKey())){
                    GroupVo groupVo = new GroupVo();
    
                    groupVo.setNo(String.valueOf(groupNo++));
                    groupVo.setName(EmojiConverter.convert(entry.getValue().getNickName()));
                    groupVo.setNum(String.valueOf(entry.getValue().getMemberCount()));  
                    groupVo.setUnderCtrl(false);
                    groupVo.setSignIn(false);
                    
                    //groupVo.setUserName(entry.getValue().getUserName());
                    groupVo.setUserName(SimpleCipher.encrypt(entry.getValue().getUserName()));
    
                    groupList.add(groupVo);
                }  
            }            
        }
                        	    
	    return groupList;	    	    
	}
	
	public static List<FriendVo> getFriendList(){

	    List<FriendVo> list = new ArrayList<>();
	    
        //先填充管理员
        for(Map.Entry<String, Contact> entry : InMemoryStorage.friendMap.entrySet()){
            if(InMemoryStorage.userGroupCtrlEntity.getAdminList().contains(entry.getKey())){

                FriendVo vo = new FriendVo();
                
                vo.setNickName(EmojiConverter.convert(entry.getKey()));
                
                if(entry.getValue().getSex() == 1){
                    vo.setSex("男");
                }else if (entry.getValue().getSex() == 2){
                    vo.setSex("女");
                }else{
                    vo.setSex("Ta不想说");
                }
                
                vo.setProvince(entry.getValue().getProvince());

                vo.setCity(entry.getValue().getCity());
                
                vo.setIsAdmin(true);
                
                if(InMemoryStorage.userGroupCtrlEntity.getNoticeReceiverList().contains(entry.getKey())){
                    vo.setReceiveMsg(true);
                }else{
                    vo.setReceiveMsg(false);
                }

                //vo.setUserName(entry.getValue().getUserName());
                vo.setUserName(SimpleCipher.encrypt(entry.getValue().getUserName()));                    
                
                list.add(vo);
            }
        }

        //再填充其他好友
        for(Map.Entry<String, Contact> entry : InMemoryStorage.friendMap.entrySet()){
            if(!InMemoryStorage.userGroupCtrlEntity.getAdminList().contains(entry.getKey())){
                
                FriendVo vo = new FriendVo();
                
                vo.setNickName(EmojiConverter.convert(entry.getKey()));
                
                if(entry.getValue().getSex() == 1){
                    vo.setSex("男");
                }else if (entry.getValue().getSex() == 2){
                    vo.setSex("女");
                }else{
                    vo.setSex("Ta不想说");
                }
                
                vo.setProvince(entry.getValue().getProvince());

                vo.setCity(entry.getValue().getCity());
                
                vo.setIsAdmin(false);
                
                vo.setReceiveMsg(false);

                //vo.setUserName(entry.getValue().getUserName());    
                vo.setUserName(SimpleCipher.encrypt(entry.getValue().getUserName()));                    

                list.add(vo);

            }
        }
        
        return list;
	}
	
    public static List<MemberVo> getMemberList(String groupUserName){

        List<MemberVo> list = new ArrayList<>();
	        
        String group = InMemoryStorage.findGroupNickName(groupUserName);

        if(group != null){
            Contact groupContact = InMemoryStorage.groupMap.get(group);
    
            if(groupContact.getMemberList() != null){
                
                // 填充数据
                for(Contact member : groupContact.getMemberList()){
                    
                    MemberVo mv = new MemberVo();
                    
                    mv.setNickName(EmojiConverter.convert(member.getNickName()));
                    mv.setNickNameInGroup(EmojiConverter.convert(member.getDisplayName()));
                    mv.setSignInToday(false);
                    mv.setNumOfWeek(0);
                    mv.setNumOfTotal(0);
                    mv.setOriginalNickName(member.getNickName());
                    
                    SignInRecord record = null;
    
                    try {
                        record = LogicProcess.findSignInInfo(group);
                    } catch (IOException e) {
                        logger.info(Exceptions.getExceptionDetail(e));
                    }
    
                    if(record != null){
    
                        if(record.getRecord() != null){
                            for(SignInRecordItem recordItem: record.getRecord()){
    
                                if(recordItem.getGroup().equals(group)){
    
                                    for(SignInDetail detail: recordItem.getDetail()){
    
                                        if(detail.getMember().equals(member.getNickName())){
    
                                            Calendar calendar = Calendar.getInstance(); 
                                            calendar.setTimeInMillis(System.currentTimeMillis());   
                                            int day = calendar.get(Calendar.DAY_OF_MONTH);
    
                                            if(detail.getDay() == day){
                                                //今天打卡了
                                                mv.setSignInToday(true);
                                            }
    
                                            mv.setNumOfWeek(detail.getTimes());
                                            mv.setNumOfTotal(detail.getTotal());
   
                                        }
                                    }
                                }
                            }
                        }
    
                    }
                    
                    list.add(mv);
                }
            }
        }
        
        return list;
    }

    public static List<AutoReplyVo> getAutoReplyList(){
        
        List<AutoReplyVo> list = new ArrayList<>();

        for(Map.Entry<String, AutoReplyItem> entry : InMemoryStorage.autoReplyEntity.getMap().entrySet()){

            AutoReplyVo vo = new AutoReplyVo();

            StringBuilder sb = new StringBuilder();
            
            vo.setKeyword(entry.getKey());

            sb.setLength(0);
            for(String item : entry.getValue().getGroupList()){             
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }
            vo.setGroup(sb.toString());
            
            sb.setLength(0);
            for(String item : entry.getValue().getExcludedUserList()){              
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }
            vo.setIgnoredSender(sb.toString());

            sb.setLength(0);
            for(String item : entry.getValue().getTextList()){
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }
            vo.setTextMsg(sb.toString());
            
            sb.setLength(0);
            for(String item : entry.getValue().getImageList()){
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }       
            vo.setImgMsg(sb.toString());
                            
            switch (entry.getValue().getStatus()){              
                case AutoReplyItem.ENABLED:
                    vo.setEnabled(true);
                    break;
                case AutoReplyItem.DISABLED:
                    vo.setEnabled(false);
                    break;                      
                default:
                    vo.setEnabled(false);
                    break;
            }
            
            list.add(vo);                                       
        
        }   
            
        return list;
    }
    
    public static List<WelcomeMsgVo> getWelcomeMsgList(){
        
        List<WelcomeMsgVo> list = new ArrayList<>();

        for(Map.Entry<String, WelcomeMsgItem> msg : InMemoryStorage.welcomeMsgEntity.getMap().entrySet()){

            WelcomeMsgVo vo = new WelcomeMsgVo();
            
            StringBuilder sb = new StringBuilder();
            
            vo.setKeyword(msg.getKey());
            
            vo.setThreshold((msg.getValue().getThreshold()));

            sb.setLength(0);
            for(String item : msg.getValue().getGroupReceivers()){              
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }
            vo.setGroup(sb.toString());

            sb.setLength(0);
            for(String item : msg.getValue().getTextList()){
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }
           vo.setTextMsg(sb.toString());
            
            sb.setLength(0);
            for(String item : msg.getValue().getImageList()){
                if(StringUtils.isNotBlank(item)){
                      sb.append("[").append(item).append("]   ");
                }
            }       
           vo.setImgMsg(sb.toString());
                            
            switch (msg.getValue().getMsgStatus()){             
                case WelcomeMsgItem.ENABLED:
                    vo.setEnabled(true);
                    break;
                case WelcomeMsgItem.DISABLED:
                    vo.setEnabled(false);
                    break;                      
                default:
                    vo.setEnabled(false);
                    break;
            }
            
            list.add(vo);                                                       
        }      
                    
        return list;
    } 
    
    public static List<ScheduledTaskVo> getScheduledTaskList(){
        
        List<ScheduledTaskVo> list = new ArrayList<>();
        
        for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){
            
            ScheduledTaskVo vo = new ScheduledTaskVo();

            String className = StringUtils.substring(task.getValue().getJobClassName(), 
                                StringUtils.lastIndexOf(task.getValue().getJobClassName(), ".") + 1);           
                        
            if(className.equals("CommonJob")){
                //先填充CommonJob
                
                StringBuilder sb = new StringBuilder();
                
                vo.setKeyword(task.getKey());
                vo.setScheduledTime(task.getValue().getScheduledTime());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getGroupReceivers()){             
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setGroupReceivers(sb.toString());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getFriendReceivers()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setFriendReceivers(sb.toString());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getTextList()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setTextMsg(sb.toString());
                
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getImageList()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }       
                vo.setImgMsg(sb.toString());
                
                vo.setJobClassName(className);
                
                switch (task.getValue().getTaskStatus()){               
                    case ScheduledTaskItem.READY:
                        vo.setEnabled(true);
                        break;
                    case ScheduledTaskItem.PAUSE:
                        vo.setEnabled(false);
                        break;                      
                    default:
                        vo.setEnabled(false);
                        break;
                }
                
                list.add(vo);                                                 
            }           
        }
        
        for(Map.Entry<String, ScheduledTaskItem> task : InMemoryStorage.scheduledTaskEntity.getMap().entrySet()){
            
            ScheduledTaskVo vo = new ScheduledTaskVo();

            String className = StringUtils.substring(task.getValue().getJobClassName(), 
                                StringUtils.lastIndexOf(task.getValue().getJobClassName(), ".") + 1);
            
            if(!className.equals("CommonJob")){
                //再填充非CommonJob
                
                StringBuilder sb = new StringBuilder();
                
                vo.setKeyword(task.getKey());
                vo.setScheduledTime(task.getValue().getScheduledTime());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getGroupReceivers()){             
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setGroupReceivers(sb.toString());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getFriendReceivers()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setFriendReceivers(sb.toString());
    
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getTextList()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }
                vo.setTextMsg(sb.toString());
                
                sb.setLength(0);
                for(String item : task.getValue().getCustomData().getImageList()){
                    if(StringUtils.isNotBlank(item)){
                          sb.append("[").append(item).append("]   ");
                    }
                }       
                vo.setImgMsg(sb.toString());
                
                vo.setJobClassName(className);
                
                switch (task.getValue().getTaskStatus()){               
                    case ScheduledTaskItem.READY:
                        vo.setEnabled(true);
                        break;
                    case ScheduledTaskItem.PAUSE:
                        vo.setEnabled(false);
                        break;                      
                    default:
                        vo.setEnabled(false);
                        break;
                }
                
                list.add(vo);                              
            }           
        }       
                
        return list;
    }
    
    public static List<AdminVo> getAdminList(){
        
        List<AdminVo> list = new ArrayList<>();

        Gson gson = new Gson();
        String content = null;
        
        //===========================================================
        //加载用户、微信群控制信息

        try {
            content = FileUtil.read(Constant.adminFile, Constant.encoding);
        } catch (IOException e1) {
            logger.info("读取文件[{}]异常", Constant.adminFile);
            return list;
        }

        if(content == null){
            logger.info("文件[{}]不存在", Constant.adminFile);

        }else{

            //logger.info("文件[{}]存在，内容是：{}", Constant.adminFile, content);

           //通过JsonParser对象把json格式的字符串解析成一个JsonElement对象
            JsonElement el = new JsonParser().parse(content);
            
            //把JsonElement对象转换成JsonArray
            JsonArray array = null;
            if(el.isJsonArray()){
                array = el.getAsJsonArray();
            }
            
            //遍历JsonArray对象
            Iterator<JsonElement> it = array.iterator();
            
            while(it.hasNext()){
                JsonElement e = it.next();
            
                //JsonElement转换为JavaBean对象
                AdminVo entity = gson.fromJson(e, AdminVo.class);
                list.add(entity);
            }                        
        }
        
        return list;
    }
    
    public static AdminVo getAdmin(String account){
                
        AdminVo entity = null;
        
        List<AdminVo> list = getAdminList();
        
        for(AdminVo item : list){
            if(item.getAccount().equals(account)){
                entity = new AdminVo();

                entity.setAccount(item.getAccount());
                entity.setPassword(item.getPassword());
                entity.setStatus(item.getStatus());
            }
        }
        
        return entity;
    }
    
    public static boolean enableAdmin(String account){
                
        List<AdminVo> list = getAdminList();
        
        for(AdminVo item : list){
            if(item.getAccount().equals(account)){
                item.setStatus(AdminVo.ENABLED);
            }
        }
        
        return saveAdminListToFile(list);
    }
    
    public static boolean disableAdmin(String account){
        
        List<AdminVo> list = getAdminList();
        
        for(AdminVo item : list){
            if(item.getAccount().equals(account)){
                item.setStatus(AdminVo.DISABLED);
            }
        }
        
        return saveAdminListToFile(list);
    }
    
    public static boolean removeAdmin(String account){
        
        List<AdminVo> list = getAdminList();     
        Iterator<AdminVo> it = list.iterator();
        boolean foundAndDeleted = false;
        
        while(it.hasNext()){
            AdminVo x = it.next();
            if(x.getAccount().equals(account)){
                it.remove();
                foundAndDeleted = true;
            }
        }
        
        if(foundAndDeleted){
            return saveAdminListToFile(list);         
        }
        
        return true;
    }
    
    public static boolean createOrModifyAdmin(AdminVo entity, boolean isCreate){

        List<AdminVo> list = getAdminList();     
        Iterator<AdminVo> it = list.iterator();

        if(!isCreate){
            while(it.hasNext()){
                AdminVo x = it.next();
                if(x.getAccount().equals(entity.getAccount())){
                    it.remove();
                }
            } 
        }

        list.add(entity);

        return saveAdminListToFile(list);
    }
    
    private static boolean saveAdminListToFile(List<AdminVo> list){
        
        Gson gson = new Gson();
        String content = gson.toJson(list);

        try {
            FileUtil.write(Constant.adminFile, content, Constant.encoding, false);
        } catch (IOException e) {
            logger.info(Exceptions.getExceptionDetail(e));
            return false;
        }   
        
        return true;
    }
    
    public static String getSystemLog(){
        
        String content = null;
        
        RandomAccessFile raf = null;
        
        try{
            raf = new RandomAccessFile(Constant.logFile, "r"); 
                    
            long fileLength = raf.length();
            int lengthToDisplay = 0;
            int lengthLimit = 10000;
            
            if(fileLength > lengthLimit){
                lengthToDisplay = lengthLimit;
                raf.seek(fileLength - lengthLimit);
            }else{
                lengthToDisplay = (int) fileLength;
                raf.seek(0);
            }
            
            byte[] buff=new byte[lengthToDisplay];
            
            raf.read(buff);//将内容写入buff字节数组中  
            
            content = new String(buff, Constant.encoding);

        }catch (Exception e){
            content = "系统日志读取失败，请重试";
        }
        
        return content;    
    }
}

		
